home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Tools / lynx-2.4 / WWW / Library / Implementation / HTRules.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-28  |  10.7 KB  |  417 lines

  1. /*    Configuration manager for Hypertext Daemon        HTRules.c
  2. **    ==========================================
  3. **
  4. **
  5. ** History:
  6. **     3 Jun 91    Written TBL
  7. **    10 Aug 91    Authorisation added after Daniel Martin (pass, fail)
  8. **            Rule order in file changed
  9. **            Comments allowed with # on 1st char of rule line
  10. **      17 Jun 92       Bug fix: pass and fail failed if didn't contain '*' TBL
  11. **       1 Sep 93       Bug fix: no memory check - Nathan Torkington
  12. **                      BYTE_ADDRESSING removed - Arthur Secret
  13. **    11 Sep 93  MD    Changed %i into %d in debug printf. 
  14. **            VMS does not recognize %i.
  15. **            Bug Fix: in case of PASS, only one parameter to printf.
  16. **    19 Sep 93  AL    Added Access Authorization stuff.
  17. **     1 Nov 93  AL    Added htbin.
  18. **
  19. */
  20.  
  21. /* (c) CERN WorldWideWeb project 1990,91. See Copyright.html for details */
  22. #include "HTRules.h"
  23.  
  24. #include "HTUtils.h"
  25. #include "tcp.h"
  26. /*#include <stdio.h> included by HTUtils.h -- FM */
  27. #include "HTFile.h"
  28. #include "HTAAServ.h"    /* Access Authorization */
  29.  
  30. #include "LYLeaks.h"
  31.  
  32. #define LINE_LENGTH 256
  33.  
  34.  
  35. typedef struct _rule {
  36.     struct _rule *    next;
  37.     HTRuleOp    op;
  38.     char *        pattern;
  39.     char *        equiv;
  40. } rule;
  41.  
  42. /*    Global variables
  43. **    ----------------
  44. */
  45. PUBLIC char *HTBinDir = NULL;    /* Physical /htbin directory path.    */
  46.                                 /* In future this should not be global.    */
  47. PUBLIC char *HTSearchScript = NULL;    /* Search script name.        */
  48.  
  49.  
  50. /*    Module-wide variables
  51. **    ---------------------
  52. */
  53.  
  54. PRIVATE rule * rules = 0;    /* Pointer to first on list */
  55. #ifndef PUT_ON_HEAD
  56. PRIVATE rule * rule_tail = 0;    /* Pointer to last on list */
  57. #endif
  58.  
  59.  
  60. /*    Add rule to the list                    HTAddRule()
  61. **    --------------------
  62. **
  63. **  On entry,
  64. **    pattern        points to 0-terminated string containing a single "*"
  65. **    equiv        points to the equivalent string with * for the
  66. **            place where the text matched by * goes.
  67. **  On exit,
  68. **    returns        0 if success, -1 if error.
  69. */
  70.  
  71. #ifdef __STDC__
  72. PUBLIC int HTAddRule (HTRuleOp op, const char * pattern, const char * equiv)
  73. #else
  74. int HTAddRule(op, pattern, equiv)
  75.     HTRuleOp    op;
  76.     char *    pattern;
  77.     char *    equiv;
  78. #endif
  79. { /* BYTE_ADDRESSING removed and memory check - AS - 1 Sep 93 */
  80.     rule *      temp;
  81.     char *      pPattern;
  82.  
  83.     temp = (rule *)malloc(sizeof(*temp));
  84.     if (temp==NULL) 
  85.     outofmem(__FILE__, "HTAddRule"); 
  86.     pPattern = (char *)malloc(strlen(pattern)+1);
  87.     if (pPattern==NULL) 
  88.     outofmem(__FILE__, "HTAddRule"); 
  89.     if (equiv) {        /* Two operands */
  90.     char *    pEquiv = (char *)malloc(strlen(equiv)+1);
  91.     if (pEquiv==NULL) 
  92.         outofmem(__FILE__, "HTAddRule"); 
  93.         temp->equiv = pEquiv;
  94.         strcpy(pEquiv, equiv);
  95.     } else {
  96.         temp->equiv = 0;
  97.     }
  98.     temp->pattern = pPattern;
  99.     temp->op = op;
  100.  
  101.     strcpy(pPattern, pattern);
  102.     if (TRACE) {
  103.        if (equiv)
  104.           fprintf(stderr, "Rule: For `%s' op %d `%s'\n", pattern, op, equiv);
  105.        else
  106.           fprintf(stderr, "Rule: For `%s' op %d\n", pattern, op);
  107.     }
  108.  
  109. #ifdef PUT_ON_HEAD
  110.     temp->next = rules;
  111.     rules = temp;
  112. #else
  113.     temp->next = 0;
  114.     if (rule_tail) rule_tail->next = temp;
  115.     else rules = temp;
  116.     rule_tail = temp;
  117. #endif
  118.  
  119.         
  120.     return 0;
  121. }
  122.  
  123.  
  124. /*    Clear all rules                        HTClearRules()
  125. **    ---------------
  126. **
  127. ** On exit,
  128. **    There are no rules
  129. **    returns        0 if success, -1 if error.
  130. **
  131. ** See also
  132. **    HTAddRule()
  133. */
  134. #ifdef __STDC__
  135. int HTClearRules(void)
  136. #else
  137. int HTClearRules()
  138. #endif
  139. {
  140.     while (rules) {
  141.         rule * temp = rules;
  142.     rules = temp->next;
  143.     free(temp->pattern);
  144.     free(temp->equiv);
  145.     free(temp);
  146.     }
  147. #ifndef PUT_ON_HEAD
  148.     rule_tail = 0;
  149. #endif
  150.  
  151.     return 0;
  152. }
  153.  
  154.  
  155. /*    Translate by rules                    HTTranslate()
  156. **    ------------------
  157. **
  158. **    The most recently defined rules are applied first.
  159. **
  160. ** On entry,
  161. **    required    points to a string whose equivalent value is neeed
  162. ** On exit,
  163. **    returns        the address of the equivalent string allocated from
  164. **            the heap which the CALLER MUST FREE. If no translation
  165. **            occured, then it is a copy of te original.
  166. ** NEW FEATURES:
  167. **            When a "protect" or "defprot" rule is mathed,
  168. **            a call to HTAA_setCurrentProtection() or
  169. **            HTAA_setDefaultProtection() is made to notify
  170. **            the Access Authorization module that the file is
  171. **            protected, and so it knows how to handle it.
  172. **                                -- AL
  173. */
  174. #ifdef __STDC__
  175. char * HTTranslate(const char * required)
  176. #else
  177. char * HTTranslate(required)
  178.     char * required;
  179. #endif
  180. {
  181.     rule * r;
  182.     char *current = NULL;
  183.     StrAllocCopy(current, required);
  184.  
  185.     HTAA_clearProtections();    /* Reset from previous call -- AL */
  186.  
  187.     for(r = rules; r; r = r->next) {
  188.         char * p = r->pattern;
  189.     int m=0;   /* Number of characters matched against wildcard */
  190.     CONST char * q = current;
  191.     for(;*p && *q; p++, q++) {   /* Find first mismatch */
  192.         if (*p!=*q) break;
  193.     }
  194.  
  195.     if (*p == '*') {        /* Match up to wildcard */
  196.         m = strlen(q) - strlen(p+1); /* Amount to match to wildcard */
  197.         if(m<0) continue;           /* tail is too short to match */
  198.         if (0!=strcmp(q+m, p+1)) continue;    /* Tail mismatch */
  199.     } else                 /* Not wildcard */
  200.         if (*p != *q) continue;    /* plain mismatch: go to next rule */
  201.  
  202.     switch (r->op) {        /* Perform operation */
  203.  
  204. #ifdef ACCESS_AUTH
  205.     case HT_DefProt:
  206.     case HT_Protect:
  207.         {
  208.         char *local_copy = NULL;
  209.         char *p;
  210.         char *eff_ids = NULL;
  211.         char *prot_file = NULL;
  212.  
  213.         if (TRACE) fprintf(stderr,
  214.                    "HTRule: `%s' matched %s %s: `%s'\n",
  215.                    current,
  216.                    (r->op==HT_Protect ? "Protect" : "DefProt"),
  217.                    "rule, setup",
  218.                    (r->equiv ? r->equiv :
  219.                     (r->op==HT_Protect ?"DEFAULT" :"NULL!!")));
  220.  
  221.         if (r->equiv) {
  222.             StrAllocCopy(local_copy, r->equiv);
  223.             p = local_copy;
  224.             prot_file = HTNextField(&p);
  225.             eff_ids = HTNextField(&p);
  226.         }
  227.  
  228.         if (r->op == HT_Protect)
  229.             HTAA_setCurrentProtection(current, prot_file, eff_ids);
  230.         else
  231.             HTAA_setDefaultProtection(current, prot_file, eff_ids);
  232.  
  233.         FREE(local_copy);
  234.  
  235.         /* continue translating rules */
  236.         }
  237.         break;
  238. #endif /* ACCESS_AUTH */
  239.  
  240.     case HT_Pass:                /* Authorised */
  241.             if (!r->equiv) {
  242.             if (TRACE) fprintf(stderr, "HTRule: Pass `%s'\n", current);
  243.             return current;
  244.             }
  245.         /* Else fall through ...to map and pass */
  246.         
  247.     case HT_Map:
  248.         if (*p == *q) { /* End of both strings, no wildcard */
  249.                   if (TRACE) fprintf(stderr,
  250.                    "For `%s' using `%s'\n", current, r->equiv);  
  251.               StrAllocCopy(current, r->equiv); /* use entire translation */
  252.         } else {
  253.           char * ins = strchr(r->equiv, '*');    /* Insertion point */
  254.               if (ins) {    /* Consistent rule!!! */
  255.             char * temp = (char *)malloc(
  256.                 strlen(r->equiv)-1 + m + 1);
  257.             if (temp==NULL) 
  258.                 outofmem(__FILE__, "HTTranslate"); /* NT & AS */
  259.             strncpy(temp,     r->equiv, ins-r->equiv);
  260.             /* Note: temp may be unterminated now! */
  261.             strncpy(temp+(ins-r->equiv), q, m);  /* Matched bit */
  262.             strcpy (temp+(ins-r->equiv)+m, ins+1);    /* Last bit */
  263.                 if (TRACE) fprintf(stderr, "For `%s' using `%s'\n",
  264.                         current, temp);
  265.             free(current);
  266.             current = temp;            /* Use this */
  267.  
  268.             } else {    /* No insertion point */
  269.             char * temp = (char *)malloc(strlen(r->equiv)+1);
  270.             if (temp==NULL) 
  271.                 outofmem(__FILE__, "HTTranslate"); /* NT & AS */
  272.             strcpy(temp, r->equiv);
  273.                 if (TRACE) fprintf(stderr, "For `%s' using `%s'\n",
  274.                         current, temp);
  275.             free(current);
  276.             current = temp;            /* Use this */
  277.             } /* If no insertion point exists */
  278.         }
  279.         if (r->op == HT_Pass) {
  280.             if (TRACE) fprintf(stderr, "HTRule: ...and pass `%s'\n",
  281.                            current);
  282.             return current;
  283.         }
  284.         break;
  285.  
  286.     case HT_Invalid:
  287.     case HT_Fail:                /* Unauthorised */
  288.                 if (TRACE) fprintf(stderr, "HTRule: *** FAIL `%s'\n",
  289.                            current);
  290.             return (char *)0;
  291.                         
  292.     } /* if tail matches ... switch operation */
  293.  
  294.     } /* loop over rules */
  295.  
  296.  
  297.     return current;
  298. }
  299.  
  300. /*    Load one line of configuration
  301. **    ------------------------------
  302. **
  303. **    Call this, for example, to load a X resource with config info.
  304. **
  305. ** returns    0 OK, < 0 syntax error.
  306. */
  307. PUBLIC int  HTSetConfiguration ARGS1(CONST char *, config)
  308. {
  309.     HTRuleOp op;
  310.     char * line = NULL;
  311.     char * pointer = line;
  312.     char *word1, *word2, *word3;
  313.     float quality, secs, secs_per_byte;
  314.     int status;
  315.     
  316.     StrAllocCopy(line, config);
  317.     {
  318.     char * p = strchr(line, '#');    /* Chop off comments */
  319.     if (p) *p = 0;
  320.     }
  321.     pointer = line;
  322.     word1 = HTNextField(&pointer);
  323.     if (!word1) {
  324.         free(line);
  325.     return 0;
  326.     } ;    /* Comment only or blank */
  327.  
  328.     word2 = HTNextField(&pointer);
  329.  
  330.     if (0==strcasecomp(word1, "defprot") ||
  331.     0==strcasecomp(word1, "protect"))
  332.     word3 = pointer;  /* The rest of the line to be parsed by AA module */
  333.     else
  334.     word3 = HTNextField(&pointer);    /* Just the next word */
  335.  
  336.     if (!word2) {
  337.     fprintf(stderr, "HTRule: Insufficient operands: %s\n", line);
  338.     free(line);
  339.     return -2;    /*syntax error */
  340.     }
  341.  
  342.     if (0==strcasecomp(word1, "suffix")) {
  343.         char * encoding = HTNextField(&pointer);
  344.     if (pointer) status = sscanf(pointer, "%f", &quality);
  345.     else status = 0;
  346.     HTSetSuffix(word2,    word3,
  347.                 encoding ? encoding : "binary",
  348.                 status >= 1? quality : 1.0);
  349.  
  350.     } else if (0==strcasecomp(word1, "presentation")) {
  351.         if (pointer) status = sscanf(pointer, "%f%f%f",
  352.                 &quality, &secs, &secs_per_byte);
  353.         else status = 0;
  354.     HTSetPresentation(word2, word3,
  355.             status >= 1? quality         : 1.0,
  356.             status >= 2 ? secs             : 0.0,
  357.             status >= 3 ? secs_per_byte     : 0.0 );
  358.  
  359.     } else if (0==strncasecomp(word1, "htbin", 5) ||
  360.            0==strncasecomp(word1, "bindir", 6)) {
  361.     StrAllocCopy(HTBinDir, word2);    /* Physical /htbin location */
  362.  
  363.     } else if (0==strncasecomp(word1, "search", 6)) {
  364.     StrAllocCopy(HTSearchScript, word2);    /* Search script name */
  365.  
  366.     } else {
  367.     op =    0==strcasecomp(word1, "map")  ?    HT_Map
  368.         :    0==strcasecomp(word1, "pass") ?    HT_Pass
  369.         :    0==strcasecomp(word1, "fail") ?    HT_Fail
  370.         :   0==strcasecomp(word1, "defprot") ? HT_DefProt
  371.         :    0==strcasecomp(word1, "protect") ? HT_Protect
  372.         :                        HT_Invalid;
  373.     if (op==HT_Invalid) {
  374.         fprintf(stderr, "HTRule: Bad rule `%s'\n", config);
  375.     } else {  
  376.         HTAddRule(op, word2, word3);
  377.     } 
  378.     }
  379.     free(line);
  380.     return 0;
  381. }
  382.  
  383.  
  384. /*    Load the rules from a file                HTLoadRules()
  385. **    --------------------------
  386. **
  387. ** On entry,
  388. **    Rules can be in any state
  389. ** On exit,
  390. **    Any existing rules will have been kept.
  391. **    Any new rules will have been loaded.
  392. **    Returns        0 if no error, 0 if error!
  393. **
  394. ** Bugs:
  395. **    The strings may not contain spaces.
  396. */
  397.  
  398. int HTLoadRules ARGS1(CONST char *, filename)
  399. {
  400.     FILE * fp = fopen(filename, "r");
  401.     char line[LINE_LENGTH+1];
  402.     
  403.     if (!fp) {
  404.         if (TRACE) fprintf(stderr,
  405.                "HTRules: Can't open rules file %s\n", filename);
  406.     return -1; /* File open error */
  407.     }
  408.     for(;;) {
  409.     if (!fgets(line, LINE_LENGTH+1, fp)) break;    /* EOF or error */
  410.     (void) HTSetConfiguration(line);
  411.     }
  412.     fclose(fp);
  413.     return 0;        /* No error or syntax errors ignored */
  414. }
  415.  
  416.  
  417.